package com.csthink.mysql.repository;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.enums.SqlMethod;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.csthink.mysql.constant.DbConstant;
import com.csthink.mysql.entity.User;
import com.csthink.mysql.mapper.UserMapper;
import lombok.Setter;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.ibatis.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.stereotype.Repository;

import java.util.List;

/**
 * @author <a href="mailto:security.2009@live.cn">Mars</a>
 * @since 2023-09-10
 */
@Repository
@CacheConfig(cacheNames = {DbConstant.TABLE_USER_NAME_KEY_FORMAT})
public class UserRepository {

    @Setter(onMethod_ = @Autowired)
    private UserMapper userMapper;

//    @CacheEvict(key = "@userKey.fromUserIds(#p0?.![#this.id])", condition = "@userCacheCondition.isEnableNewUserCache()")
    public boolean saveUserBatch(List<User> users) {
        if (CollectionUtils.isEmpty(users)) {
            return false;
        }
        String sqlStatement = SqlHelper.getSqlStatement(UserMapper.class, SqlMethod.INSERT_ONE);
        return SqlHelper.executeBatch(User.class, LogFactory.getLog(this.getClass()),
                users, 1000, ((sqlSession, entity) -> {
                    sqlSession.insert(sqlStatement, entity);
                }));
    }

    public void deleteByAccountId(String accountId) {
        LambdaQueryWrapper<User> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.eq(User::getAccountId, accountId);
        userMapper.delete(queryWrapper);
    }

//    @CacheEvict(key = "@userKey.fromUserIds(#p0)", condition = "@userCacheCondition.isEnableNewUserCache()", beforeInvocation = true)
    public void deleteByIds(List<String> userIdList) {
        userMapper.deleteBatchIds(userIdList);
    }

//    @CacheEvict(key = "@userKey.fromUserId(#p0.id)", condition = "@userCacheCondition.isEnableNewUserCache()")
    public int updateByUserId(User user) {
        return userMapper.updateById(user);
    }

    public List<User> loadByUserIds(List<String> userIdList) {
        LambdaQueryWrapper<User> queryUserWrapper = Wrappers.lambdaQuery();
        queryUserWrapper.in(User::getId, userIdList);
        return userMapper.selectList(queryUserWrapper);
    }

//    @Cacheable(
//            key = "{T(com.csthink.cache.constant.CacheConstant).TABLE_USER_GROUP_USER_ID, #p0}",
//            condition = "@cacheAspect.isConditionPassing(T(com.csthink.mysql.constant.DbConstant).TABLE_USER_NAME) && @userCacheCondition.isEnableNewUserCache()")
    public User getById(String userId) {
        return userMapper.selectById(userId);
    }

    public User loadUsersByUsername(String username) {
        LambdaQueryWrapper<User> queryUserWrapper = Wrappers.lambdaQuery();
        queryUserWrapper.eq(User::getName, username);
        return userMapper.selectOne(queryUserWrapper);
    }
}
